home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / circuits / spice2g6.z / spice2g6 / spice / Fortran / noise.f < prev    next >
Encoding:
Text File  |  1989-02-03  |  13.2 KB  |  416 lines

  1.       subroutine noise(loco)
  2.       implicit double precision (a-h,o-z)
  3. c
  4. c     this routine computes the noise due to various circuit elements.
  5. c
  6. c spice version 2g.6  sccsid=tabinf 3/15/83
  7.       common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
  8.      1   isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
  9.      2   junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
  10.      3   nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
  11.      4   lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
  12.      5   imynl,imvn,lcvn,nsnod,nsmat,nsval,icnod,icmat,icval,
  13.      6   loutpt,lpol,lzer,irswpf,irswpr,icswpf,icswpr,irpt,jcpt,
  14.      7   irowno,jcolno,nttbr,nttar,lvntmp
  15. c spice version 2g.6  sccsid=cirdat 3/15/83
  16.       common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
  17.      1   nut,nlt,nxtrm,ndist,ntlin,ibr,numvs,numalt,numcyc
  18. c spice version 2g.6  sccsid=status 3/15/83
  19.       common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet,
  20.      1   xmu,sfactr,mode,modedc,icalc,initf,method,iord,maxord,noncon,
  21.      2   iterno,itemno,nosolv,modac,ipiv,ivmflg,ipostp,iscrch,iofile
  22. c spice version 2g.6  sccsid=miscel 3/15/83
  23.       common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
  24.      1  defas,rstats(50),iwidth,lwidth,nopage
  25. c spice version 2g.6  sccsid=knstnt 3/15/83
  26.       common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok,
  27.      1   gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox,
  28.      2   pivtol,pivrel
  29. c spice version 2g.6  sccsid=ac 3/15/83
  30.       common /ac/ fstart,fstop,fincr,skw2,refprl,spw2,jacflg,idfreq,
  31.      1   inoise,nosprt,nosout,nosin,idist,idprt
  32. c spice version 2g.6  sccsid=blank 3/15/83
  33.       common /blank/ value(200000)
  34.       integer nodplc(64)
  35.       complex cvalue(32)
  36.       equivalence (value(1),nodplc(1),cvalue(1))
  37. c
  38. c
  39.       dimension vno1(12),vno2(12),vno3(12),vno4(12),vno5(12),vno6(12)
  40.       dimension vntot(12),anam(12),string(5)
  41.       real v,vreal,vimag
  42.       dimension titln(4),v(2)
  43.       dimension afmt1(3),afmt2(3)
  44.       complex cval,c(1)
  45.       equivalence (c(1),v(1),cval)
  46.       equivalence (v(1),vreal),(v(2),vimag)
  47.       data titln / 8hnoise an, 8halysis  , 8h        , 8h         /
  48.       data alsrb,alsrc,alsre,alsrs,alsrd / 2hrb,2hrc,2hre,2hrs,2hrd /
  49.       data alsib,alsic,alsid,alsfn / 2hib,2hic,2hid,2hfn /
  50.       data alstot / 5htotal /
  51.       data aslash,ablnk / 1h/, 1h  /
  52.       data afmt1 /8h(////,11,8hx,  (2x,,8ha8))    /
  53.       data afmt2 /8h(1h0,a8,,8h1p  d10.,8h3)      /
  54. c
  55. c
  56. c.. fix-up formats
  57.       kntr=12
  58.       if(lwidth.le.80) kntr=7
  59.       ipos=11
  60.       call move(afmt1,ipos,ablnk,1,2)
  61.       call alfnum(kntr,afmt1,ipos)
  62.       ipos=11
  63.       call move(afmt2,ipos,ablnk,1,2)
  64.       call alfnum(kntr,afmt2,ipos)
  65.       nprnt=0
  66.       freq=omega/twopi
  67.       if (icalc.ge.2) go to 10
  68.       fourkt=4.0d0*charge*vt
  69.       twoq=2.0d0*charge
  70.       noposo=nodplc(nosout+2)
  71.       nonego=nodplc(nosout+3)
  72.       kntlim=lwidth/11
  73.       nkntr=1
  74.    10 if (nosprt.eq.0) go to 30
  75.       if (nkntr.gt.icalc) go to 30
  76.       nprnt=1
  77.       nkntr=nkntr+nosprt
  78.       call title(0,lwidth,1,titln)
  79.       write (iofile,16) freq
  80.    16 format('0    frequency = ',1pd10.3,' hz'/)
  81. c
  82. c  obtain adjoint circuit solution
  83. c
  84.    30 vnrms=0.0d0
  85.       cval=cvalue(lcvn+noposo)-cvalue(lcvn+nonego)
  86.       vout=dsqrt(dble(vreal*vreal)+dble(vimag*vimag))
  87.       vout=dmax1(vout,1.0d-20)
  88.       call zero8(value(lvn+1),nstop)
  89.       call zero8(value(imvn+1),nstop)
  90.       value(lvn+noposo)=-1.0d0
  91.       value(lvn+nonego)=+1.0d0
  92.       call acasol
  93. c
  94. c  resistors
  95. c
  96.       if (jelcnt(1).eq.0) go to 200
  97.       ititle=0
  98.    91 format(//'0**** resistor squared noise voltages (sq v/hz)')
  99.   100 loc=locate(1)
  100.       kntr=0
  101.   110 if ((loc.eq.0).or.(nodplc(loc+8).ne.0)) go to 130
  102.       kntr=kntr+1
  103.       locv=nodplc(loc+1)
  104.       anam(kntr)=value(locv)
  105.       node1=nodplc(loc+2)
  106.       node2=nodplc(loc+3)
  107.       cval=cvalue(lcvn+node1)-cvalue(lcvn+node2)
  108.       vntot(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))
  109.      1   *fourkt*value(locv+1)
  110.       vnrms=vnrms+vntot(kntr)
  111.       if (kntr.ge.kntlim) go to 140
  112.   120 loc=nodplc(loc)
  113.       go to 110
  114.   130 if (kntr.eq.0) go to 200
  115.   140 if (nprnt.eq.0) go to 160
  116.       if (ititle.eq.0) write (iofile,91)
  117.       ititle=1
  118.       write (iofile,afmt1) (anam(i),i=1,kntr)
  119.       write (iofile,afmt2) alstot,(vntot(i),i=1,kntr)
  120.   160 kntr=0
  121.       if (loc.ne.0) go to 120
  122. c
  123. c  diodes
  124. c
  125.   200 if (jelcnt(11).eq.0) go to 300
  126.       ititle=0
  127.   201 format(//'0**** diode squared noise voltages (sq v/hz)')
  128.   210 loc=locate(11)
  129.       kntr=0
  130.   220 if ((loc.eq.0).or.(nodplc(loc+16).ne.0)) go to 240
  131.       kntr=kntr+1
  132.       locv=nodplc(loc+1)
  133.       anam(kntr)=value(locv)
  134.       node1=nodplc(loc+2)
  135.       node2=nodplc(loc+3)
  136.       node3=nodplc(loc+4)
  137.       locm=nodplc(loc+5)
  138.       locm=nodplc(locm+1)
  139.       loct=nodplc(loc+11)
  140.       area=value(locv+1)
  141.       fnk=value(locm+10)
  142.       fna=value(locm+11)
  143. c
  144. c  ohmic resistance
  145. c
  146.       cval=cvalue(lcvn+node1)-cvalue(lcvn+node3)
  147.       vno1(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))
  148.      1   *fourkt*value(locm+2)*area
  149. c
  150. c  junction shot noise and flicker noise
  151. c
  152.       cval=cvalue(lcvn+node3)-cvalue(lcvn+node2)
  153.       vtemp=dble(vreal*vreal)+dble(vimag*vimag)
  154.       arg=dmax1(dabs(value(lx0+loct+1)),1.0d-20)
  155.       vno2(kntr)=vtemp*twoq*arg
  156.       vno3(kntr)=vtemp*fnk*dexp(fna*dlog(arg))/freq
  157.       vntot(kntr)=vno1(kntr)+vno2(kntr)+vno3(kntr)
  158.       vnrms=vnrms+vntot(kntr)
  159.       if (kntr.ge.kntlim) go to 250
  160.   230 loc=nodplc(loc)
  161.       go to 220
  162.   240 if (kntr.eq.0) go to 300
  163.   250 if (nprnt.eq.0) go to 260
  164.       if (ititle.eq.0) write (iofile,201)
  165.       ititle=1
  166.       write (iofile,afmt1) (anam(i),i=1,kntr)
  167.       write (iofile,afmt2) alsrs,(vno1(i),i=1,kntr)
  168.       write (iofile,afmt2) alsid,(vno2(i),i=1,kntr)
  169.       write (iofile,afmt2) alsfn,(vno3(i),i=1,kntr)
  170.       write (iofile,afmt2) alstot,(vntot(i),i=1,kntr)
  171.   260 kntr=0
  172.       if (loc.ne.0) go to 230
  173. c
  174. c  bipolar junction transistors
  175. c
  176.   300 if (jelcnt(12).eq.0) go to 400
  177.       ititle=0
  178.   301 format(//'0**** transistor squared noise voltages (sq v/hz)')
  179.   310 loc=locate(12)
  180.       kntr=0
  181.   320 if ((loc.eq.0).or.(nodplc(loc+36).ne.0)) go to 340
  182.       kntr=kntr+1
  183.       locv=nodplc(loc+1)
  184.       anam(kntr)=value(locv)
  185.       node1=nodplc(loc+2)
  186.       node2=nodplc(loc+3)
  187.       node3=nodplc(loc+4)
  188.       node4=nodplc(loc+5)
  189.       node5=nodplc(loc+6)
  190.       node6=nodplc(loc+7)
  191.       locm=nodplc(loc+8)
  192.       locm=nodplc(locm+1)
  193.       loct=nodplc(loc+22)
  194.       area=value(locv+1)
  195.       fnk=value(locm+44)
  196.       fna=value(locm+45)
  197. c
  198. c  extrinsic resistances
  199. c
  200. c...  base resistance
  201.       cval=cvalue(lcvn+node2)-cvalue(lcvn+node5)
  202.       vno1(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))
  203.      1  *fourkt*value(lx0+loct+16)
  204. c...  collector resistance
  205.       cval=cvalue(lcvn+node1)-cvalue(lcvn+node4)
  206.       vno2(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))
  207.      1   *fourkt*value(locm+20)*area
  208. c...  emitter resistance
  209.       cval=cvalue(lcvn+node3)-cvalue(lcvn+node6)
  210.       vno3(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))
  211.      1   *fourkt*value(locm+19)*area
  212. c
  213. c  base current shot noise and flicker noise
  214. c
  215.       cval=cvalue(lcvn+node5)-cvalue(lcvn+node6)
  216.       vtemp=dble(vreal*vreal)+dble(vimag*vimag)
  217.       arg=dmax1(dabs(value(lx0+loct+3)),1.0d-20)
  218.       vno4(kntr)=vtemp*twoq*arg
  219.       vno5(kntr)=vtemp*fnk*dexp(fna*dlog(arg))/freq
  220. c
  221. c  collector current shot noise
  222. c
  223.       cval=cvalue(lcvn+node4)-cvalue(lcvn+node6)
  224.       vno6(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))
  225.      1   *twoq*dabs(value(lx0+loct+2))
  226.       vntot(kntr)=vno1(kntr)+vno2(kntr)+vno3(kntr)+vno4(kntr)+vno5(kntr)
  227.      1   +vno6(kntr)
  228.       vnrms=vnrms+vntot(kntr)
  229.       if (kntr.ge.kntlim) go to 350
  230.   330 loc=nodplc(loc)
  231.       go to 320
  232.   340 if (kntr.eq.0) go to 400
  233.   350 if (nprnt.eq.0) go to 360
  234.       if (ititle.eq.0) write (iofile,301)
  235.       ititle=1
  236.       write (iofile,afmt1) (anam(i),i=1,kntr)
  237.       write (iofile,afmt2) alsrb,(vno1(i),i=1,kntr)
  238.       write (iofile,afmt2) alsrc,(vno2(i),i=1,kntr)
  239.       write (iofile,afmt2) alsre,(vno3(i),i=1,kntr)
  240.       write (iofile,afmt2) alsib,(vno4(i),i=1,kntr)
  241.       write (iofile,afmt2) alsic,(vno6(i),i=1,kntr)
  242.       write (iofile,afmt2) alsfn,(vno5(i),i=1,kntr)
  243.       write (iofile,afmt2) alstot,(vntot(i),i=1,kntr)
  244.   360 kntr=0
  245.       if (loc.ne.0) go to 330
  246. c
  247. c  jfets
  248. c
  249.   400 if (jelcnt(13).eq.0) go to 500
  250.       ititle=0
  251.   401 format(//'0**** jfet squared noise voltages (sq v/hz)')
  252.   410 loc=locate(13)
  253.       kntr=0
  254.   420 if ((loc.eq.0).or.(nodplc(loc+25).ne.0)) go to 440
  255.       kntr=kntr+1
  256.       locv=nodplc(loc+1)
  257.       anam(kntr)=value(locv)
  258.       node1=nodplc(loc+2)
  259.       node2=nodplc(loc+3)
  260.       node3=nodplc(loc+4)
  261.       node4=nodplc(loc+5)
  262.       node5=nodplc(loc+6)
  263.       locm=nodplc(loc+7)
  264.       locm=nodplc(locm+1)
  265.       loct=nodplc(loc+19)
  266.       area=value(locv+1)
  267.       fnk=value(locm+10)
  268.       fna=value(locm+11)
  269. c
  270. c  extrinsic resistances
  271. c
  272. c...  drain resistance
  273.       cval=cvalue(lcvn+node1)-cvalue(lcvn+node4)
  274.       vno1(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))
  275.      1   *fourkt*value(locm+4)*area
  276. c...  source resistance
  277.       cval=cvalue(lcvn+node3)-cvalue(lcvn+node5)
  278.       vno2(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))
  279.      1   *fourkt*value(locm+5)*area
  280. c
  281. c  drain current shot noise and flicker noise
  282. c
  283.       cval=cvalue(lcvn+node4)-cvalue(lcvn+node5)
  284.       vtemp=dble(vreal*vreal)+dble(vimag*vimag)
  285.       vno3(kntr)=vtemp*fourkt*2.0d0*dabs(value(lx0+loct+5))/3.0d0
  286.       arg=dmax1(dabs(value(lx0+loct+3)),1.0d-20)
  287.       vno4(kntr)=vtemp*fnk*dexp(fna*dlog(arg))/freq
  288.       vntot(kntr)=vno1(kntr)+vno2(kntr)+vno3(kntr)+vno4(kntr)
  289.       vnrms=vnrms+vntot(kntr)
  290.       if (kntr.ge.kntlim) go to 450
  291.   430 loc=nodplc(loc)
  292.       go to 420
  293.   440 if (kntr.eq.0) go to 500
  294.   450 if (nprnt.eq.0) go to 460
  295.       if (ititle.eq.0) write (iofile,401)
  296.       ititle=1
  297.       write (iofile,afmt1) (anam(i),i=1,kntr)
  298.       write (iofile,afmt2) alsrd,(vno1(i),i=1,kntr)
  299.       write (iofile,afmt2) alsrs,(vno2(i),i=1,kntr)
  300.       write (iofile,afmt2) alsid,(vno3(i),i=1,kntr)
  301.       write (iofile,afmt2) alsfn,(vno4(i),i=1,kntr)
  302.       write (iofile,afmt2) alstot,(vntot(i),i=1,kntr)
  303.   460 kntr=0
  304.       if (loc.ne.0) go to 430
  305. c
  306. c  mosfets
  307. c
  308.   500 if (jelcnt(14).eq.0) go to 600
  309.       ititle=0
  310.   501 format(//'0**** mosfet squared noise voltages (sq v/hz)')
  311.   510 loc=locate(14)
  312.       kntr=0
  313.   520 if ((loc.eq.0).or.(nodplc(loc+33).ne.0)) go to 540
  314.       kntr=kntr+1
  315.       locv=nodplc(loc+1)
  316.       anam(kntr)=value(locv)
  317.       node1=nodplc(loc+2)
  318.       node2=nodplc(loc+3)
  319.       node3=nodplc(loc+4)
  320.       node4=nodplc(loc+5)
  321.       node5=nodplc(loc+6)
  322.       node6=nodplc(loc+7)
  323.       locm=nodplc(loc+8)
  324.       itype=nodplc(locm+2)
  325.       loct=nodplc(loc+26)
  326.       locm=nodplc(locm+1)
  327.       xl=value(locv+1)-2.0d0*value(locm+28)
  328.       xw=value(locv+2)
  329.       cox=value(locm+22)
  330.       if (cox.le.0.0d0) cox=epsox/1.0d-7
  331.       fnk=value(locm+36)
  332.       fna=value(locm+37)
  333. c
  334. c  extrinsic resistances
  335. c
  336.       if ((value(locm+7).le.0.0d0).and.
  337.      1   (value(locm+8).le.0.0d0)) go to 522
  338.       gdpr=value(locm+7)
  339.       gspr=value(locm+8)
  340.       go to 524
  341.   522 gdpr=value(locm+16)/value(locv+13)
  342.       gspr=value(locm+16)/value(locv+14)
  343. c...  drain resistance
  344.   524 cval=cvalue(lcvn+node1)-cvalue(lcvn+node5)
  345.       vno1(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))*fourkt*gdpr
  346. c...  source resistance
  347.       cval=cvalue(lcvn+node3)-cvalue(lcvn+node6)
  348.       vno2(kntr)=(dble(vreal*vreal)+dble(vimag*vimag))*fourkt*gspr
  349. c
  350. c  drain current shot noise and flicker noise
  351. c
  352.       cval=cvalue(lcvn+node5)-cvalue(lcvn+node6)
  353.       vtemp=dble(vreal*vreal)+dble(vimag*vimag)
  354.       gm=value(lx0+loct+7)
  355.       arg=dmax1(dabs(value(lx0+loct+4)),1.0d-20)
  356.       vno3(kntr)=vtemp*fourkt*dabs(gm)/1.5d0
  357.       vno4(kntr)=vtemp*fnk*dexp(fna*dlog(arg))/(freq*cox*xl*xl)
  358.   525 vntot(kntr)=vno1(kntr)+vno2(kntr)+vno3(kntr)+vno4(kntr)
  359.       vnrms=vnrms+vntot(kntr)
  360.       if (kntr.ge.kntlim) go to 550
  361.   530 loc=nodplc(loc)
  362.       go to 520
  363.   540 if (kntr.eq.0) go to 600
  364.   550 if (nprnt.eq.0) go to 560
  365.       if (ititle.eq.0) write (iofile,501)
  366.       ititle=1
  367.       write (iofile,afmt1) (anam(i),i=1,kntr)
  368.       write (iofile,afmt2) alsrd,(vno1(i),i=1,kntr)
  369.       write (iofile,afmt2) alsrs,(vno2(i),i=1,kntr)
  370.       write (iofile,afmt2) alsid,(vno3(i),i=1,kntr)
  371.       write (iofile,afmt2) alsfn,(vno4(i),i=1,kntr)
  372.       write (iofile,afmt2) alstot,(vntot(i),i=1,kntr)
  373.   560 kntr=0
  374.       if (loc.ne.0) go to 530
  375. c
  376. c  compute equivalent input noise voltage
  377. c
  378.   600 vnout=dsqrt(vnrms)
  379.       vnin=vnout/vout
  380.       if (nprnt.eq.0) go to 620
  381.       do 610 i=1,5
  382.       string(i)=ablnk
  383.   610 continue
  384.       ioutyp=1
  385.       ipos=1
  386.       call outnam(nosout,ioutyp,string,ipos)
  387.       call move(string,ipos,aslash,1,1)
  388.       ipos=ipos+1
  389.       locv=nodplc(nosin+1)
  390.       anam1=value(locv)
  391.       call move(string,ipos,anam1,1,8)
  392.       write (iofile,611) vnrms,vnout,string,vout,anam1,vnin
  393.   611 format(////,
  394.      1   '0**** total output noise voltage',9x,'= ',1pd10.3,' sq v/hz'/,
  395.      2   1h0,40x,'= ',d10.3,' v/rt hz'/,
  396.      3   '0     transfer function value:',/,
  397.      4   1h0,7x,4a8,a1,'= ',d10.3,/,
  398.      5   '0     equivalent input noise at ',a8,' = ',d10.3,' /rt hz')
  399. c
  400. c  save noise outputs
  401. c
  402.   620 loc=locate(44)
  403.   630 if (loc.eq.0) go to 1000
  404.       iseq=nodplc(loc+4)
  405.       if (nodplc(loc+5).ne.2) go to 640
  406.       cvalue(loco+iseq)=vnout
  407.       go to 650
  408.   640 cvalue(loco+iseq)=vnin
  409.   650 loc=nodplc(loc)
  410.       go to 630
  411. c
  412. c  finished
  413. c
  414.  1000 return
  415.       end
  416.